/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "../guidefaults.h"
#include "../Frame.h"

namespace gui {

Frame::Frame(const std::string &title, bool draggable)
:	m_bOpen(true),
	m_bDraggable(draggable),
	m_bDragging(false),
	m_uiActiveTab(0),
	m_iDragBarSize(0)
{
	m_sTitle = title;
	if (m_bDraggable) 
		m_iDragBarSize = iRowSize;
}


Frame::~Frame(void)
{
}

void Frame::addCanvas(Canvas *canvas)
{
	int yoff = 0;
	Component::add(canvas);

	if (components.size() > 1) {
		yoff += iRowSize+2;
		canvas->setVisible(false);
	}
	
	comp_list::iterator it;
	for (it = components.begin(); it != components.end(); ++it) {
		(*it)->setPosition(0, m_iDragBarSize+yoff);
		setSize(max(vDim.x, (*it)->getSize().x), max(vDim.y, (*it)->getSize().y+m_iDragBarSize+yoff));
	}
}

void Frame::removeCanvas(Canvas *canvas)
{
	Component::remove(canvas);
}

void Frame::setFont(IFont *font) 
{
	Component::setFont(font);
	m_iDragBarSize = iRowSize+2;
}

bool Frame::setActiveTab(unsigned int tabIndex)
{
	if (tabIndex >= components.size()) 
		return false;

	components.at(m_uiActiveTab)->setVisible(false);
	m_uiActiveTab = tabIndex;
	components.at(m_uiActiveTab)->setVisible(true);
	return true;
}

void Frame::draw()
{
	int xoff, yoff, width;

	if (bVisible) {		
		if (!pTexture) {
			// Draw upper frame
			if (m_bDraggable) {
				pRenderer->drawFilledRect(vPos.x, vPos.y, vDim.x+2, m_iDragBarSize, vBorderColor);
				//font->setColor(vTextColor);
				font->print(m_sTitle, vPos.x+vOffset.x, vPos.y+vOffset.y, 0, FONT_LEFT, 0, 0, vTextColor);
			}

			// Draw tabs
			xoff  = vPos.x;
			yoff  = vPos.y + m_iDragBarSize;
			width = static_cast<int>( vDim.x / static_cast<float>(components.size()) );
		} else {
			pTexture->display(vPos.x, vPos.y, 1, true);
		}

		if (components.size() > 1) {
			for (comp_list::const_iterator it = components.begin(); it != components.end(); ++it) {
				Canvas *c = (Canvas*) *it;
				pRenderer->drawFilledRect(xoff, yoff, width, iRowSize, vBackColor);
				pRenderer->drawRect(xoff, yoff, width, iRowSize, vBorderColor);
				//font->setColor(vTextColor);
				font->print(c->getTitle(), xoff + vOffset.x, yoff + vOffset.y, 0, FONT_LEFT, width, iRowSize, vTextColor); 
				xoff += width;
			}
			yoff += iRowSize;
		}

		if (components.size() > 0) {
			// Draw the active component
			components.at(m_uiActiveTab)->draw();	
		}
	}
}

void Frame::onMousePressed(const MouseEvent &me)
{
	Component::onMousePressed(me);
	// Bring the frame to front
	bringToFront();
	// See if a tab was pressed
	if (components.size() > 0) {
		if ( me.x > vRealPos.x && me.x < vRealPos.x + vDim.x + m_iDragBarSize && 
			 me.y > vRealPos.y + m_iDragBarSize && me.y < vRealPos.y + m_iDragBarSize + iRowSize)
		{
			setActiveTab( static_cast<unsigned int>( components.size()*(me.x - vRealPos.x)/vDim.x ) );
		}
	}
	// If draggable, enter drag mode
	if (m_bDraggable) {
		if ( me.x > vRealPos.x && me.x < vRealPos.x + vDim.x && 
			 me.y > vRealPos.y && me.y < vRealPos.y + m_iDragBarSize) 
		{
			m_bDragging = true;
			vDragOffset = math::Vector2i(me.x, me.y) - getAbsolutePosition();
		}
	}
}

void Frame::onMouseReleased(const MouseEvent &me)
{
	Component::onMouseReleased(me);
	m_bDragging = false;
}

bool Frame::processMouse(int _x, int _y, int _z, int _button)
{
	//bool retval = false;
	if (Component::processMouse(_x, _y, _z, _button)) {

		if (m_bDragging) {
			vPos = math::Vector2i(_x, _y) - vDragOffset;
		}
		return true;
	}
	return false;
}

const bool Frame::isDraggable() const
{
	return m_bDraggable;
}

} // namespace
